Skip to content

Fix problems in checking that a constructor is uninhabited for exhaustive match checking #23403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2025

Conversation

Alex1005a
Copy link
Contributor

  1. If the field with bottom type is lazy, then the constructor is inhabited.
  2. Now it is taken into account that the type member can be Nothing and the field can be this type member.
  3. The check has been moved to the inhabited function, allowing some changes to be reverted from Do not consider uninhabited constructors when performing exhaustive match checking #21750

I was also thinking about making the check recursive, i.e. checking that all fields are inhabited. This could cause problems with cycles and performance, so I'm not sure whether to do it.

@Alex1005a Alex1005a marked this pull request as ready for review June 22, 2025 17:32
@Alex1005a Alex1005a force-pushed the bottom-types-coverage-fix branch from 584b8e1 to 0696aec Compare June 22, 2025 19:47
@Gedochao Gedochao requested a review from mbovel June 26, 2025 08:12
Copy link
Member

@mbovel mbovel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my non-Space-engine-expert eyes this looks good to me.

Nice to see a PR that also removes some code!

I was also thinking about making the check recursive, i.e. checking that all fields are inhabited. This could cause problems with cycles and performance, so I'm not sure whether to do it.

Would the recursive check help in that situation for example?

sealed trait T
case class A(x: String) extends T
case class B(x: Nothing) extends T  // uninhabited

sealed trait T2
case class A2(x: String) extends T2
case class B2(x: B) extends T2  // indirectly uninhabited

@main def Test =
  (??? : T) match
    case A(_) => ???

  (??? : T2) match
    case A2(_) => ??? // warn: match may not be exhaustive
                      // Do we want to remove this warning?

Do we have real examples where that would be useful?

I’d merge this as-is and revisit deeper checks later if a concrete use-case turns up.

@Alex1005a
Copy link
Contributor Author

Would the recursive check help in that situation for example?

Yes, exactly.

Do we have real examples where that would be useful?

Probably not. It might be useful for codebases that will heavily use this approach with Nothing fields. Maybe something like "Trees that grow" (using type members for example).

Anyway, I think for now we can merge this as is.

@mbovel mbovel merged commit 470e012 into scala:main Jul 14, 2025
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants